﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace LinqToDB.Provider
{
    class SqlProvider:IQueryProvider
    {
        /// <summary>
        /// 表达式简化器
        /// </summary>
        ExpressionSimplify m_expSimple = new ExpressionSimplify();
        /// <summary>
        /// 表达式打印
        /// </summary>
        ExpressionPrinter m_expPrint = new ExpressionPrinter();
        /// <summary>
        /// 节点转换器
        /// </summary>
        SqlNodeConvertor m_nodeConvert = new SqlNodeConvertor();
        /// <summary>
        /// 节点简化器
        /// </summary>
        SqlNodeSimplify m_nodeSimple = new SqlNodeSimplify();
        /// <summary>
        /// 节点打印
        /// </summary>
        SqlNodePrinter m_nodePrint = new SqlNodePrinter();

        public SqlProvider()
        { 
            
        }

        public object Execute(Expression expression)
        {
            //1 简化
            expression = m_expSimple.Visit(expression);
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("------------转换前---------------");
            m_expPrint.Visit(expression);

            
            //2 转换
            SqlNode node = m_nodeConvert.Convert(expression);

            //3 再简化
            node = m_nodeSimple.Visit(node);
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("------------转换后---------------");
            m_nodePrint.Visit(node);


            //输出
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("------------结果---------------");
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(node.ToString());

            //查询
            return Activator.CreateInstance(
                typeof(List<>).MakeGenericType(expression.Type.GetGenericArguments()[0]));
        }

        #region Provider接口实现
        IQueryable<TElement> IQueryProvider.CreateQuery<TElement>(Expression expression)
        {
            return (IQueryable<TElement>)this.Execute(expression);
        }

        IQueryable IQueryProvider.CreateQuery(Expression expression)
        {
            return (IQueryable)this.Execute(expression);
        }

        TResult IQueryProvider.Execute<TResult>(Expression expression)
        {
            return (TResult)this.Execute(expression);
        }

        object IQueryProvider.Execute(Expression expression)
        {
            return this.Execute(expression);
        }
        #endregion
    }
}
